﻿using System;
using System.Drawing.Imaging;
using System.IO;
using System.Transactions;
using System.Drawing;
using TeamsPortal.DataAccess;

namespace TeamsPortal.ServiceClient
{
    public interface IImageService
    {
        ImageInfo Add(string path, User editor);
        void SetAvatar(Image image, User user);
        ImageInfo Get(int id);
    }

    public class ImageService : IImageService
    {
        private readonly IUsersServiceClient _userServiceClient;
        private readonly IFileStorageService _fileStorage;

        public ImageService(IUsersServiceClient userServiceClient, IFileStorageService fileStorage)
        {
            _userServiceClient = userServiceClient;
            _fileStorage = fileStorage;
        }

        public void SetAvatar(Image image, User user)
        {
            string path;
            using (Stream imgStream = createImageStream(image, ImageFormat.Png))
            {
                path = _fileStorage.SaveStream(imgStream, ".png");
            }

            //note: Provider doesn't support remoting transactions.
            //note: Consider moving transaction to db side.
            //using (var scope = new TransactionScope())
            {
                if (user.AvatarId.HasValue)
                {
                    ImageInfo oldAvatar = Get(user.AvatarId.Value);
                    if (oldAvatar == null) {
                        throw new Exception("There is no avatar with id: " + user.AvatarId.Value);
                    }
                    Remove(oldAvatar.Id);
                    _fileStorage.Remove(oldAvatar.Path);
                }
                ImageInfo img = Add(path, user);
                _userServiceClient.SetAvatar(user.Id, img);

            //    scope.Complete();
            }
        }

        public ImageInfo Add(string path, User editor)
        {
            var da = new ImageInfoDataAccess();
            ImageInfo img = da.Add(path, editor.Id);

            return img;
        }

        public ImageInfo Get(int id)
        {
            var da = new ImageInfoDataAccess();
            ImageInfo img = da.Get(id);

            return img;
        }

        private static Stream createImageStream(Image img, ImageFormat format)
        {
            var stream = new MemoryStream();
            img.Save(stream, format);
            stream.Position = 0;

            return stream;
        }

        private static void Remove(int id)
        {
            var da = new ImageInfoDataAccess();
            da.Remove(id);
        }
    }
}
